package com.zw.a.basic.a14.demo10_tcp_exercise;

import java.io.*;
import java.net.Socket;

//自定义的资源类, 每监听到一个客户端连接, 就执行一次(文件上传操作.)
public class ServerThread2 implements Runnable {
    //定义变量, 用来记录要和此客户端交互的 Socket对象.
    private Socket accept;

    public ServerThread2(Socket accept) {
        this.accept = accept;
    }

    @Override
    public void run() {
        BufferedWriter bw = null;
        try {

            //解决文件名冲突的问题
            int count = 1;
            File file = new File("day14/data/copy(" + count + ").txt");      //copy1.txt
            while(file.exists()) {   //文件存在, 就不断往下判断
                count++;
                file = new File("day14/data/copy(" + count + ").txt");       //copy2.txt, copy3.txt, copy4.txt...
            }

            //3. 创建字符高效流, 封装目的地文件.
            bw = new BufferedWriter(new FileWriter(file));
            //4. 通过Socket#getInputStream()获取输入流, 可以读取客户端写过来的数据,
            //为了写入方便, 将其封装成: 字符高效流.
            BufferedReader br = new BufferedReader(new InputStreamReader(accept.getInputStream()));
            //5. 定义变量, 记录读取到的数据.
            String line;
            //6. 循环读取, 只要条件满足, 就一直读, 并将读取到的内容赋值给变量line
            while ((line = br.readLine()) != null) {   //循环没有结束, 因为没有接收到客户端写过来的 null
                //7. 将读取到的内容写到目的地文件中.
                bw.write(line);
                bw.newLine();
                bw.flush();
            }

            //8. 获取输出流, 可以往客户端写数据.
            BufferedWriter bw2 = new BufferedWriter(new OutputStreamWriter(accept.getOutputStream()));
            //9. 给客户端返回一个回执信息"上传成功"
            bw2.write("文件上传成功");
            bw2.newLine();      //细节1: 必须写换行符, 因为等会儿在客户端我们是通过 readLine()来读取一行数据的, 它的结束标记就是 换行符
            bw2.flush();        //细节2: 必须写, 不然数据还在缓冲区, 客户端收不到.
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            //10. 释放资源.
            try {
               if (bw != null) {
                   bw.close();
                   bw = null;   //GC会优先回收null对象.
               }
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                try {
                   if (accept != null) {
                       accept.close();
                       accept = null;
                   }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}
